Constructing arguments of system commands from user input is security-sensitive. It has led in the past to the following vulnerabilities:
Arguments of system commands are processed by the executed program. The arguments are usually used to configure and influence the behavior of the
programs. Control over a single argument might be enough for an attacker to trigger dangerous features like executing arbitrary commands or writing
files into specific directories.
Ask Yourself Whether
  -  Malicious arguments can result in undesired behavior in the executed command. 
-  Passing user input to a system command is not necessary. 
There is a risk if you answered yes to any of those questions.
Recommended Secure Coding Practices
  -  Avoid constructing system commands from user input when possible. 
-  Ensure that no risky arguments can be injected for the given program, e.g., type-cast the argument to an integer. 
-  Use a more secure interface to communicate with other programs, e.g., the standard input stream (stdin). 
Sensitive Code Example
Arguments like -delete or -exec for the find command can alter the expected behavior and result in
vulnerabilities:
import (
	"fmt"
	"net/http"
	"os/exec"
)
func ListDirectory(w http.ResponseWriter, req *http.Request) {
	dirs := req.URL.Query()["dir"]
	output, _ := exec.Command("/usr/bin/find", dirs...).CombinedOutput() // Sensitive
	fmt.Fprintf(w, "Output: %s", output)
}
Compliant Solution
Use an allow-list to restrict the arguments to trusted values:
import (
	"fmt"
	"net/http"
	"os/exec"
)
var allowed = map[string]bool{"/tmp": true}
func ListDirectory(w http.ResponseWriter, req *http.Request) {
	dirs := req.URL.Query()["dir"]
	for _, dir := range dirs {
		if _, ok := allowed[dir]; !ok { // Validator
			fmt.Fprintf(w, "Error")
			return
		}
	}
	output, _ := exec.Command("/usr/bin/find", dirs...).CombinedOutput()
	fmt.Fprintf(w, "Output: %s", output)
}
See